// Abstract interface to return function/file/line info for a memory address.

#ifndef LONGKEY_BREAKPAD_PROCESSOR_SOURCE_LINE_RESOLVER_INTERFACE_H_
#define LONGKEY_BREAKPAD_PROCESSOR_SOURCE_LINE_RESOLVER_INTERFACE_H_

#include <string>

namespace longkey_breakpad
{
	using std::string;

	struct StackFrame;
	struct WindowsFrameInfo;
	struct CFIFrameInfo;

	class SourceLineResolverInterface
	{
	public:
		typedef u_int64_t MemAddr;

		virtual ~SourceLineResolverInterface() {}

		// Adds a module to this resolver, returning true on success.
		//
		// module should have at least the code_file, debug_file,
		// and debug_identifier members populated.
		//
		// map_file should contain line/address mappings for this module.
		virtual bool LoadModule(const CodeModule *module,
			const string &map_file) = 0;
		// Same as above, but takes the contents of a pre-read map buffer
		virtual bool LoadModuleUsingMapBuffer(const CodeModule *module,
			const string &map_buffer) = 0;

		// Add an interface to load symbol using C-String data insteading string.
		// This is useful in the optimization design for avoiding unnecessary copying
		// of symbol data, in order to improve memory efficiency.
		// LoadModuleUsingMemoryBuffer() does NOT take ownership of memory_buffer.
		virtual bool LoadModuleUsingMemoryBuffer(const CodeModule *module,
			char *memory_buffer) = 0;

		// Return true if the memory buffer should be deleted immediately after
		// LoadModuleUsingMemoryBuffer(). Return false if the memory buffer has to be
		// alive during the lifetime of the corresponding Module.
		virtual bool ShouldDeleteMemoryBufferAfterLoadModule() = 0;

		// Request that the specified module be unloaded from this resolver.
		// A resolver may choose to ignore such a request.
		virtual void UnloadModule(const CodeModule *module) = 0;

		// Returns true if the module has been loaded.
		virtual bool HasModule(const CodeModule *module) = 0;

		// Fills in the function_base, function_name, source_file_name,
		// and source_line fields of the StackFrame.  The instruction and
		// module_name fields must already be filled in.
		virtual void FillSourceLineInfo(StackFrame *frame) = 0;

		// If Windows stack walking information is available covering
		// FRAME's instruction address, return a WindowsFrameInfo structure
		// describing it. If the information is not available, returns NULL.
		// A NULL return value does not indicate an error. The caller takes
		// ownership of any returned WindowsFrameInfo object.
		virtual WindowsFrameInfo *FindWindowsFrameInfo(const StackFrame *frame) = 0;

		// If CFI stack walking information is available covering ADDRESS,
		// return a CFIFrameInfo structure describing it. If the information
		// is not available, return NULL. The caller takes ownership of any
		// returned CFIFrameInfo object.
		virtual CFIFrameInfo *FindCFIFrameInfo(const StackFrame *frame) = 0;

	protected:
		// SourceLineResolverInterface cannot be instantiated except by subclasses
		SourceLineResolverInterface() {}
	};
}
#endif	// LONGKEY_BREAKPAD_PROCESSOR_SOURCE_LINE_RESOLVER_INTERFACE_H_